﻿namespace SharePointCSVImporter
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Runtime.Serialization;

    [DataContract]
    public class Configuration : INotifyPropertyChanged
    {
        #region Fields

        private List<string> csvColumns;
        private int duplicateKeyAction;
        private List<CSVParser.FieldMapping> fieldMappings;
        private List<Microsoft.SharePoint.Client.Field> fields;
        private bool isConfigured;
        private bool overwriteExistingValues;
        private PropertyChangedEventHandler propertychanged;
        private string targetListName;
        private string targetWebUrl;

        #endregion Fields

        #region Constructors

        public Configuration()
        {
        }

        public Configuration(List<string> columnNames)
        {
            this.csvColumns = columnNames;
            ReadFromStorage();
            if (fieldMappings != null)
            {
                this.IsConfigured = true;
            }
        }

        #endregion Constructors

        #region Events

        event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
        {
            add { this.propertychanged += value; }
            remove { this.propertychanged -= value; }
        }

        #endregion Events

        #region Properties

        public List<string> CsvColumns
        {
            get { return csvColumns; }
            set { csvColumns = value; }
        }

        //0 is do nothing 1 is update latest 2 is update latest and delete others
        [DataMember]
        public int DuplicateKeyAction
        {
            get { return duplicateKeyAction; }
            set { duplicateKeyAction = value; }
        }

        [DataMember]
        public List<CSVParser.FieldMapping> FieldMappings
        {
            get { return fieldMappings; }
            set { fieldMappings = value; OnPropertyChanged("FieldMappings"); }
        }

        public List<Microsoft.SharePoint.Client.Field> Fields
        {
            get { return fields; }
            set { fields = value; OnPropertyChanged("Fields"); }
        }

        public bool IsConfigured
        {
            get { return isConfigured; }
            set { isConfigured = value; OnPropertyChanged("IsConfigured"); }
        }

        [DataMember]
        public bool OverwriteExistingValues
        {
            get { return overwriteExistingValues; }
            set { overwriteExistingValues = value; OnPropertyChanged("OverwriteExistingValues"); }
        }

        [DataMember]
        public string TargetListName
        {
            get { return targetListName; }
            set { targetListName = value; OnPropertyChanged("TargetListName"); }
        }

        [DataMember]
        public string TargetWebUrl
        {
            get { return targetWebUrl; }
            set { targetWebUrl = value; OnPropertyChanged("TargetWebUrl"); }
        }

        #endregion Properties

        #region Methods

        public void CreateNewFieldMappings(List<string> columns)
        {
            fieldMappings = new List<CSVParser.FieldMapping>();
        }

        public void NotifyNewConfiguration()
        {
            OnPropertyChanged("TargetWebUrl");
            OnPropertyChanged("TargetListName");
            OnPropertyChanged("OverwriteExistingValues");
            OnPropertyChanged("FieldMappings");
        }

        public void Save()
        {
            if (fieldMappings != null)
            {
                ConfigManager.SaveFieldMappings(fieldMappings);
            }
            if (!string.IsNullOrEmpty(targetWebUrl))
            {
                ConfigManager.SaveWebUrl(targetWebUrl);
            }
            if (!string.IsNullOrEmpty(targetListName))
            {
                ConfigManager.SaveTargetListName(targetListName);
            }
            ConfigManager.SaveOverwriteOption(overwriteExistingValues);
            if (duplicateKeyAction > -1)
            {
                ConfigManager.SaveDupAction(duplicateKeyAction);
            }
        }

        internal void BuildFieldMappings()
        {
            lock (this)
            {
                try
                {
                    if (fieldMappings == null)
                    {
                        fieldMappings = new List<CSVParser.FieldMapping>();
                    }
                    if (fieldMappings.Any() && csvColumns != null && csvColumns.Count > 1)
                    {
                        //remove fields not in file
                        List<CSVParser.FieldMapping> columnsToRemove = new List<CSVParser.FieldMapping>();
                        foreach (var mapping in fieldMappings)
                        {
                            bool exists = csvColumns.Any(c => c.Equals(mapping.CsvColumnName));
                            if (!exists)
                            {
                                columnsToRemove.Add(mapping);
                            }
                        }
                        foreach (var removMap in columnsToRemove)
                        {
                            fieldMappings.Remove(removMap);
                        }
                    }
                }
                catch (Exception ex)
                {

                }
                if (csvColumns != null)
                {
                    foreach (string column in csvColumns)
                    {

                        int columnIndex = csvColumns.IndexOf(column);
                        if (!fieldMappings.Any(c => c.CsvColumnName.Equals(column)))
                        {
                            fieldMappings.Add(new CSVParser.FieldMapping() { CsvColumnName = column, Index = columnIndex });
                        }
                        else
                        {
                            fieldMappings.FirstOrDefault(c => c.CsvColumnName.Equals(column)).Index = columnIndex;
                        }

                    }
                }
                if (fieldMappings != null)
                {
                    fieldMappings = fieldMappings.OrderBy(c => c.Index).ToList();
                }
            }
        }

        internal void OnPropertyChanged(string propertyname)
        {
            if (propertychanged != null)
            {
                this.propertychanged(this, new PropertyChangedEventArgs(propertyname));
            }
        }

        private void ReadFromStorage()
        {
            this.fieldMappings = ConfigManager.TryGetFieldMapingsFromStorage();
            this.targetWebUrl = ConfigManager.TrygetWebFromStorage();
            this.targetListName = ConfigManager.TryGetListNameFromStorage();
            this.overwriteExistingValues = ConfigManager.TryGetOverwriteOption();
            this.duplicateKeyAction = ConfigManager.TryGetDupAction();
        }

        #endregion Methods
    }
}